package com.ydy.service.impl;

import com.ydy.enums.OrderStatusEnum;
import com.ydy.enums.YesOrNo;
import com.ydy.mapper.OrderItemsMapper;
import com.ydy.mapper.OrderStatusMapper;
import com.ydy.mapper.OrdersMapper;
import com.ydy.pojo.*;
import com.ydy.pojo.bo.SubmitOrderBO;
import com.ydy.service.AddressService;
import com.ydy.service.ItemService;
import com.ydy.service.OrderService;
import com.ydy.utils.ParamsUtil;
import com.ydy.utils.Sid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Random;

@Service
public class OrderServiceImpl implements OrderService {

    public static final Logger log =
            LoggerFactory.getLogger(OrderServiceImpl.class);

    private static final Random random = new Random();

    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private OrderItemsMapper orderItemsMapper;

    @Autowired
    private OrderStatusMapper orderStatusMapper;

    @Autowired
    private AddressService addressService;

    @Autowired
    private ItemService itemService;

    @Autowired
    private Sid sid;


    /**
     * 创建订单
     * @param submitOrderBO
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public String createOrder(SubmitOrderBO submitOrderBO) {

        String userId = submitOrderBO.getUserId();
        String addressId = submitOrderBO.getAddressId();
        String itemSpecIds = submitOrderBO.getItemSpecIds();

        String orderId = sid.nextShort();
        log.info("根据用户id:{}和地址id:{}查询地址信息",userId,addressId);
        UserAddress address = addressService.queryUserAddress(userId, addressId);

        // 1. 循环根据itemSpecIds保存订单商品信息表
        String itemSpecIdArr[] = itemSpecIds.split(",");
        Integer totalAmount = 0;    // 商品原价累计
        Integer realPayAmount = 0;  // 优惠后的实际支付价格累计
        for (String itemSpecId : itemSpecIdArr) {
            // TODO 整合redis后，商品购买的数量重新从redis的购物车中获取
            int buyCounts = 1;
            // 1.1 根据规格id，查询规格的具体信息，主要获取价格
            log.info("根据规格id:{}查询规格信息",itemSpecId);
            ItemsSpec itemSpec = itemService.queryItemSpecById(itemSpecId);
            saveOrderItems(orderId,itemSpec,buyCounts);

            totalAmount += itemSpec.getPriceNormal() * buyCounts;
            realPayAmount += itemSpec.getPriceDiscount() * buyCounts;

            // 1.2 在用户提交订单以后，规格表中需要扣除库存
            log.info("根据规格id:{}和购买数量:{}扣减库存",itemSpecId,buyCounts);
            itemService.decreaseItemSpecStock(itemSpecId, buyCounts);
        }

        // 2. 新订单数据保存
        saveOrder(submitOrderBO,address,orderId,totalAmount,realPayAmount);
        // 3. 保存订单状态表
        saveOrderStatus(orderId);

        return orderId;
    }

    /**
     * 保存订单商品
     * @param orderId 订单id
     * @param itemSpec 商品规格
     * @param buyCounts 购买数量
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveOrderItems(String orderId, ItemsSpec itemSpec, int buyCounts) {
        // 1根据商品id，获得商品信息以及商品图片
        String itemId = itemSpec.getItemId();
        log.info("根据商品id:{}查询商品信息和商品主图",itemId);
        Items item = itemService.queryItemById(itemId);
        String imgUrl = itemService.queryItemMainImgById(itemId);

        // 2 循环保存子订单数据到数据库
        String subOrderId = sid.nextShort();
        OrderItems subOrderItem = new OrderItems();
        subOrderItem.setId(subOrderId);
        subOrderItem.setOrderId(orderId);
        subOrderItem.setItemId(itemId);
        subOrderItem.setItemName(item.getItemName());
        subOrderItem.setItemImg(imgUrl);
        subOrderItem.setBuyCounts(buyCounts);
        subOrderItem.setItemSpecId(itemSpec.getId());
        subOrderItem.setItemSpecName(itemSpec.getName());
        subOrderItem.setPrice(itemSpec.getPriceDiscount());
        log.info("订单规格数据保存");
        orderItemsMapper.insert(subOrderItem);
    }

    /**
     * 保存新订单
     * @param submitOrderBO 订单数据
     * @param address 地址数据
     * @param totalAmount  总金额
     * @param realPayAmount 实际支付金额
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveOrder(SubmitOrderBO submitOrderBO, UserAddress address, String orderId, Integer totalAmount, Integer realPayAmount) {

        String userId = submitOrderBO.getUserId();
        Integer payMethod = submitOrderBO.getPayMethod();
        String leftMsg = submitOrderBO.getLeftMsg();

        // 包邮费用设置为0
        Integer postAmount = 0;

        Orders newOrder = new Orders();
        newOrder.setId(orderId);
        newOrder.setUserId(userId);

        newOrder.setReceiverName(address.getReceiver());
        newOrder.setReceiverMobile(address.getMobile());
        newOrder.setReceiverAddress(address.getProvince() + " "
                + address.getCity() + " "
                + address.getDistrict() + " "
                + address.getDetail());

        newOrder.setPostAmount(postAmount);

        newOrder.setPayMethod(payMethod);
        newOrder.setLeftMsg(leftMsg);

        newOrder.setIsComment(YesOrNo.NO.type);
        newOrder.setIsDelete(YesOrNo.NO.type);
        newOrder.setCreatedTime(new Date());
        newOrder.setUpdatedTime(new Date());
        newOrder.setTotalAmount(totalAmount);
        newOrder.setRealPayAmount(realPayAmount);
        log.info("订单数据保存");
        ordersMapper.insert(newOrder);
    }

    /**
     * 保存订单状态
     * @param orderId
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveOrderStatus(String orderId) {
        OrderStatus waitPayOrderStatus = new OrderStatus();
        waitPayOrderStatus.setOrderId(orderId);
        waitPayOrderStatus.setOrderStatus(OrderStatusEnum.WAIT_PAY.type);
        waitPayOrderStatus.setCreatedTime(new Date());
        log.info("订单状态数据保存");
        orderStatusMapper.insert(waitPayOrderStatus);

    }

    /**
     * 自动更新订单状态
     * @param orderId
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    @Async
    public void updateOrderStatus(String orderId){
        int randomNum = random.nextInt(2);
        log.info("订单状态数据更新随机数为:{}",randomNum);
        if(0 == randomNum){
            try {
                Thread.sleep(30 * 1000);
            } catch (InterruptedException e) {
                log.error(ParamsUtil.getErrorMsg(e));
            }
            OrderStatus paidStatus = new OrderStatus();
            paidStatus.setOrderId(orderId);
            paidStatus.setOrderStatus(OrderStatusEnum.WAIT_DELIVER.type);
            paidStatus.setPayTime(new Date());
            log.info("订单状态数据更新为已付款");
            orderStatusMapper.updateByPrimaryKeySelective(paidStatus);
        }else{
            log.info("订单状态数据不更新");
        }
    }

    /**
     * 根据id查询订单状态
     * @param orderId 订单id
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public OrderStatus queryOrderStatusInfo(String orderId) {
        log.info("根据订单id:{}查询订单状态数据",orderId);
        return orderStatusMapper.selectByPrimaryKey(orderId);
    }

}
